package com.eascs.dubbo.api.visa;

import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.eascs.admin.common.service.IO2oLoanapplyDubboService;
import com.eascs.admin.item.service.O2oPubDdItemService;
import com.eascs.admin.o2o.internal.entity.LoanapplyExpand;
import com.eascs.admin.o2o.internal.entity.LoanapplyExpandDetail;
import com.eascs.admin.o2o.internal.entity.PubDditem;
import com.eascs.admin.o2o.internal.service.LoanapplyExpandDetailService;
import com.eascs.admin.o2o.internal.service.LoanapplyExpandService;
import com.eascs.admin.o2o.internal.service.PubDditemService;
import com.eascs.admin.o2o.internal.service.WfTypeStatusService;
import com.eascs.admin.o2o.internal.util.BaseUserUtil;
import com.eascs.admin.o2o.internal.util.MoneyUtil;
import com.eascs.admin.o2o.internal.util.StatusContexts;
import com.eascs.admin.o2o.loan.action.ContractAndBankInfoForm;
import com.eascs.admin.o2o.loan.action.O2oBankInfoForm;
import com.eascs.admin.o2o.loan.entity.O2oLoanUserEntity;
import com.eascs.admin.o2o.loan.entity.O2oLoanapplyEntity;
import com.eascs.admin.o2o.loan.service.O2oLoanUserService;
import com.eascs.admin.o2o.loan.service.O2oLoanapplyService;
import com.eascs.admin.o2o.loan.utils.BankRate;
import com.eascs.admin.o2o.specialInterview.entity.O2OSpecialInterview;
import com.eascs.admin.o2o.specialInterview.service.O2OSpecialInterviewService;
import com.eascs.admin.o2o.visa.EditVisaService;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.common.doc.word.WordBuilder;
import com.eascs.common.exception.RuntimeIOException;
import com.eascs.common.util.DateUtils;
import com.eascs.common.util.IoUtil;
import com.eascs.common.util.StringUtil;
import com.eascs.crm.nsEditDetail.dao.MainStoreInfoDao;
import com.eascs.crm.nsEditDetail.entity.CustomerAssetInfo;
import com.eascs.crm.nsEditDetail.entity.CustomerShopInfoEntity;
import com.eascs.crm.nsEditDetail.entity.O2oMainShopInfoEntity;
import com.eascs.crm.nsEditDetail.service.CustomerAssetInfoService;
import com.eascs.crm.nsEditDetail.service.CustomerShopInfoService;
import com.eascs.crm.nsEditDetail.service.IMainShopInfoService;
import com.eascs.datalist.service.O2oDataListService;
import com.eascs.dubbo.api.util.UserUtils;
import com.eascs.file.FileTypeConstants;
import com.eascs.gaczcontract.entity.CustomerBasicInfo;
import com.eascs.site.view.BaseRestResult;
import com.eascs.web.sso.User;
import com.eascs.web.sso.UserHolder;
import com.eascs.workflow.common.entity.sys.ActOrgEntity;
import com.eascs.workflow.common.entity.wf.ProcessTemplate;
import com.eascs.workflow.common.service.sys.SysOrgService;
import com.eascs.workflow.common.service.wf.WorkFlowService;
import com.eascs.workflow.common.vo.ModelResult;
import com.eascs.workflow.common.vo.WFRequestParam;
import com.eascs.workflow.form.MQFrom;

@Service
public class EditVisaServiceImpl implements EditVisaService{
	
	private static Logger logger = LoggerFactory.getLogger(EditVisaServiceImpl.class);
	
	@Autowired
	private O2oLoanapplyService o2oLoanapplyService;
	
	@Autowired
	private O2oLoanapplyService o2oloanapplyService;
	
	@Autowired
	CustomerShopInfoService shopInfoService;
	
	@Autowired
	PubDditemService pubDditemService;
	
	@Autowired
	O2OSpecialInterviewService o2OSpecialInterviewService;
	
	@Autowired
	O2oPubDdItemService o2oPubDdItemService;
	
	@Reference
	private WorkFlowService workFlowService;
	
	@Autowired
	private O2oDataListService o2oDataListService;
	
	@Autowired
	private LoanapplyExpandService loanapplyExpandService;
	
	@Autowired
	private LoanapplyExpandDetailService loanapplyExpandDetailService;
	
	@Autowired
	MainStoreInfoDao mainStoreInfoDao;
	@Autowired
	WfTypeStatusService wfTypeStatusService;
	
	@Value("${o2o.admin.wf.sbzjUrl}")
	private String sbzjUrl;
	
	@Autowired
	private O2oLoanapplyService loanService;
	
	@Autowired
	private O2oLoanUserService loanUserService;
	
	@Autowired
	CustomerAssetInfoService assetInfoService;
	
	@Reference
	IMainShopInfoService mainShopInfoService;

	@Autowired
	O2oPubDdItemService ddItemService;
	@Reference
	SysOrgService sysOrgService;
	
	@Autowired
	BaseUserUtil userUtils;
	
	@Autowired
	IO2oLoanapplyDubboService loanapplyDubboService;

	@Override
	public O2oBankInfoForm findBankInfo(String id) {
		O2oBankInfoForm o2oBankInfoForm = new O2oBankInfoForm();
		o2oBankInfoForm = o2oLoanapplyService.findO2oBankInfoEntity(id);
		return o2oBankInfoForm;
	}

	@Override
	public void updateVisaInfo(MQFrom mqFrom) {
		o2oLoanapplyService.updateContractFlag(mqFrom);
	}

	@Override
	public O2oLoanUserEntity queryLoanUser(String loanapplyNo, String loanId) {
		O2oLoanUserEntity o2oLoanUserEntity=new O2oLoanUserEntity();
		o2oLoanUserEntity = o2oloanapplyService.findLoanUserEntity(loanapplyNo,loanId);
		return o2oLoanUserEntity;
	}

	@Override
	public void updateContra(ContractAndBankInfoForm o2oBankInfoForm) {
		O2oLoanapplyEntity o2oloanapply = o2oLoanapplyService.findById(o2oBankInfoForm.getLoanapplyno());
		o2oloanapply.setReceiveBank(o2oBankInfoForm.getBankZhiName());
		o2oloanapply.setBankAccount(o2oBankInfoForm.getBankCardNo());
		o2oLoanapplyService.updateO2oBankInfoEntity(o2oloanapply);
	}

	@Override
	public CustomerShopInfoEntity queryShopEntity(String loannaapplyNo) {
		CustomerShopInfoEntity shop = new CustomerShopInfoEntity();
		List<CustomerShopInfoEntity> infoList = shopInfoService.list(loannaapplyNo);//门店
		if (!infoList.isEmpty()) {
			if (infoList.size() > 1) {
				for (CustomerShopInfoEntity shopInfo : infoList) {
					if (shopInfo.getShoptype().equals("MAN")) {// 客户主门店里面的营业面积
						shop = shopInfo;
					}
				}
			} else {
				shop = infoList.get(0);
			}
		}
		return shop;
	}

	@Override
	public String queryAddress(String loanapplyNo) {
		O2oLoanapplyEntity loanapply = o2oloanapplyService.findById(loanapplyNo);
		O2oLoanUserEntity loanUserEntity = o2oloanapplyService.findLoanUserEntity(loanapplyNo, loanapply.getLoanId());//借款人基本信息
		CustomerBasicInfo customerBasicInfo = o2oloanapplyService.getCustomerEntityById(loanUserEntity.getId());//借款人扩展信息
		if (customerBasicInfo != null) {
			String recipientAdress="";//有效联系地址	借款人的收件地址
         	if (StringUtil.isNotBlank(customerBasicInfo.getRecipientProvince())) {
         		// 查数据字典--所在省，dd_no='9'
         		PubDditem p = pubDditemService.queryPubDditemCRM("9",customerBasicInfo.getRecipientProvince());// 所在省
				if (p != null) {
					recipientAdress=recipientAdress+p.getItemName();
				}
			}
        
			if (StringUtil.isNotBlank(customerBasicInfo.getRecipientCity())) {
				// 查数据字典--所在市，dd_no='10'
				PubDditem p = pubDditemService.queryPubDditemCRM("10",customerBasicInfo.getRecipientCity());// 所在市
				if (p != null) {
					recipientAdress=recipientAdress+p.getItemName();
				}
			}
			
			if (StringUtil.isNotBlank(customerBasicInfo.getRecipientCounty())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("11",customerBasicInfo.getRecipientCounty());// 所在县
				if (p != null) {
					recipientAdress=recipientAdress+p.getItemName();
				}
			}

			if (customerBasicInfo.getRecipientAddress() != null) {
				recipientAdress = recipientAdress + customerBasicInfo.getRecipientAddress();
			}
			return recipientAdress;
		}else {
			return null;
		}
	}

	@Override
	public void updateShopInfo(CustomerShopInfoEntity mainShop) {
		CustomerShopInfoEntity shop = shopInfoService.queryById(mainShop.getCustomerShopId());//门店信息
		
		shop.setControllername(mainShop.getControllername());
		shop.setControllerIdnum(mainShop.getControllerIdnum());
		shop.setControllerMobile(mainShop.getControllerMobile());
		//boolean flag=customerInfoService.updateStore(shop);
		shopInfoService.update(shop);
	}

	@Override
	public String submitApproval(String loanapplyNo) {
		O2oLoanapplyEntity loan = o2oLoanapplyService.findById(loanapplyNo);
		//送审银行为江西银行的单据提交面签申报不需要校验银行卡信息 
		if(!loan.getBankLoanName().equals(BankRate.BANK_JCB)){
			if (StringUtils.isEmpty(loan.getBankAccount()) || StringUtils.isEmpty(loan.getReceiveBank())) {
				return "请在《下载带数据合同》界面填写银行卡信息";
			}
		}
		/**
		 * 查询未完成还款单数，包含本单大于等于2则不能申报，小于2则可以申报
		 */
		//如果通过了特殊面签申报则不用check这一部分
		O2OSpecialInterview specialInterview =  o2OSpecialInterviewService.fingCLOFlow(loan.getLoanapplyNo());
		if(specialInterview ==null){
			int i = o2oLoanapplyService.getUserLoanCount(loan.getLoanId());// 查询为完成还款单数，包含本单大于等于2则不能申报，小于2则可以申报
			if (i >= 2) {
				return "借款人在新系统的上一笔贷款单尚未还款完，该笔贷款单不能发起申报";
			}
		}
		if (loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK) || StatusContexts.LOAN_TYPE_BP.equals(loan.getLoanType()) || StatusContexts.LOAN_TYPE_BP_JX.equals(loan.getLoanType()) || StatusContexts.LOAN_TYPE_SG.equals(loan.getLoanType()) || StatusContexts.LOAN_TYPE_YC.equals(loan.getLoanType()) || StatusContexts.LOAN_TYPE_SC.equals(loan.getLoanType())) {
			/**
			 * 判断借款人及其配偶是否有逾期和代偿的单
			 */
			// 代偿
			O2OSpecialInterview ishasSpecialInterview =  o2OSpecialInterviewService.queryEntity(loan.getLoanapplyNo());
			if(ishasSpecialInterview==null||!StatusContexts.O2O_BANK_CLO.equals(ishasSpecialInterview.getBillStatus()) ){
				int count1 = o2oLoanapplyService.findDCLoan(loan.getLoanapplyNo());
				if (count1 > 0) {
					return "借款人夫妻双方在系统中有终端贷/品牌贷 代偿，请先结清再发起面签申报";
				}
			}
		}
		/**
		 * 校验借款人历史配偶的贷款单是否全部已结清
		 * 
		 */
		
		
			Integer num = loanapplyDubboService.isSpouseExsitNotHK(loan.getLoanId(), loan.getLoanapplyNo());
			if (num > 0) {
				return "该借款人的历史配偶有未结清的贷款单";
			
		}
		
		/**
		 * 校验表达是否保存填写
		 */
		String chekSbBd = chekSbBd(loan);
		if(!chekSbBd.equals(StatusContexts.SUCCESS)){
			return chekSbBd;
		}
		
		Map<String, List<String>> roleUserMap = new HashMap<>();  //指定流程节点由谁经办
		WFRequestParam param = new WFRequestParam();
		roleUserMap.put(StatusContexts.ROLE_TYPE_NS_XDJL,Arrays.asList(loan.getOperatorNo()));
		param.setRoleUserMap(roleUserMap);
		param.setReferId(loan.getLoanapplyNo());
		param.setReferCode(loan.getBillCode());
		param.setReferUrl("http://xxxx.eascs.com/getDetail");
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK)||StatusContexts.LOAN_TYPE_BP.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_BP_JX.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_SG.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_YC.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_SC.equals(loan.getLoanType())){
			param.setProcessType(ProcessTemplate.PROECESS_TYPE_BANK_REPORT);
		}else{
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_FQ)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_EA)){
				param.setProcessType(String.valueOf(ProcessTemplate.PROECESS_TYPE_BANK_REPORT_FQ));
			}
		}
		param.setProcessVersion("v1");
		User user = UserHolder.getUser();
		param.setAppliedby(user.getNo());
		param.setAppliedbyName(user.getCname());
		param.setOrgNo(loan.getLtd());
		StringBuffer appliedDes = new StringBuffer("借款人:");
		appliedDes.append(o2oLoanapplyService.findLoanUserEntity(loan.getLoanapplyNo(),loan.getLoanId()).getUserFullName());
		appliedDes.append("，批复金额:");
		java.text.DecimalFormat df=new java.text.DecimalFormat("0.00"); //格式化，保留两位小数 
		appliedDes.append(df.format(loan.getEaMount().doubleValue()));
		appliedDes.append("，送审银行：");
		appliedDes.append(o2oPubDdItemService.findPubdditemNameByCodeisall("BANKTYPEO2O", loan.getBankLoanName()));
		param.setAppliedDes(appliedDes.toString());
		param.setLoginUser(UserUtils.getUser(user));
		ModelResult<Boolean> modelResult = workFlowService.instance(param);
		if (modelResult.isSuccess() && modelResult.getModel()) {
			o2oLoanapplyService.updateWorkFlowStatus(StatusContexts.O2O_SB_BEGIN, loanapplyNo);
			wfTypeStatusService.updatefindRUN(loan.getLoanapplyNo(), StatusContexts.WFTYPE_BRT);
		} else {
			return modelResult.getErrMsg();
		}
		return null;
	}
	
	public String chekSbBd(O2oLoanapplyEntity loanEntity){
		if (StringUtil.isEmpty(loanEntity.getContractFlag())) {
			return "合同未齐备，请点击编辑面签资料";
		}
		if (!o2oDataListService.checkCodeAttachment(loanEntity.getLoanapplyNo(), FileTypeConstants.DALIST_TYPE_CONTRACT)) {
			return "面签材料未上传，请点击编辑面签资料";
		}
		if (StatusContexts.O2O_NO.equals(loanEntity.getContractFlag())) {
			return "合同未齐备，不能发起流程，请点击编辑面签资料";
		}
		return StatusContexts.SUCCESS;
	}

	@Override
	public String submitMoeny(String loanapplyNo) {
		O2oLoanapplyEntity loan = o2oLoanapplyService.findById(loanapplyNo);
		if(loan.getBankLoanName().equals(StatusContexts.O2O_BANKTYPE_GACZ)){
			if(!loan.getWfType().equals(StatusContexts.O2O_FK_END)){ 
				return "请在面签提报流程结束后发起";
			}
		}
		
		/**
		 * 收取保证金管理费流程只能有一个，一次性缴清，如果有运行中，已经完成的状态的话，就没有必要再次在去启动流程
		 */
		LoanapplyExpand chekLoanapplyExpand = loanapplyExpandService.queryLoanapplyNo(loanapplyNo);
		LoanapplyExpandDetail loanapplyExpandDetail=loanapplyExpandDetailService.queryDetail(chekLoanapplyExpand.getId());
		if(loanapplyExpandDetail!=null){
			loanapplyExpandDetailService.delete(loanapplyExpandDetail.getId());
		}
		if(!chekLoanapplyExpand.getBillStatus().equals(StatusContexts.O2O_NEW)){
			return "保证金管理费流程已启动，请勿重复启动。";
		}
		
		WFRequestParam param = new WFRequestParam();
		Map<String, List<String>> roleUserMap = new HashMap<>();  //指定流程节点由谁经办
		roleUserMap.put(StatusContexts.ROLE_TYPE_NS_XDJL,Arrays.asList(loan.getOperatorNo()));
		param.setRoleUserMap(roleUserMap);
		param.setReferId(loan.getLoanapplyNo());
		param.setReferCode(loan.getBillCode());
		param.setReferUrl(sbzjUrl);
		param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
		if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_BK)||StatusContexts.LOAN_TYPE_BP.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_BP_JX.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_SG.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_YC.equals(loan.getLoanType())||StatusContexts.LOAN_TYPE_SC.equals(loan.getLoanType())){
			param.setProcessType(ProcessTemplate.PROECESS_TYPE_DEPOSIT);
		}else{
			if(loan.getLoanType().equals(StatusContexts.LOAN_TYPE_FQ)||loan.getLoanType().equals(StatusContexts.LOAN_TYPE_EA)){
				param.setProcessType(String.valueOf(ProcessTemplate.PROECESS_TYPE_DEPOSIT_FQ));
			}
		}
		param.setProcessVersion("v1");
		User user = UserHolder.getUser();
		if (null != user) {
			param.setAppliedby(user.getNo());
			param.setAppliedbyName(user.getCname());
		} else {
			param.setAppliedby("1");
			param.setAppliedbyName("系统管理员");
		}
		param.setOrgNo(loan.getLtd());
		StringBuffer appliedDes = new StringBuffer("借款人:");
		appliedDes.append(o2oLoanapplyService.findLoanUserEntity(loan.getLoanapplyNo(),loan.getLoanId()).getUserFullName());
		appliedDes.append("，EA批复金额:");
		java.text.DecimalFormat df=new java.text.DecimalFormat("0.00"); //格式化，保留两位小数 
		appliedDes.append(df.format(loan.getEaMount()));
		param.setAppliedDes(appliedDes.toString());
		param.setLoginUser(UserUtils.getUser(user));
		ModelResult<Boolean> modelResult = workFlowService.instance(param);
		if (modelResult.isSuccess() && modelResult.getModel()) {
			LoanapplyExpand loanapplyExpand = loanapplyExpandService.queryLoanapplyNo(loan.getLoanapplyNo());
			loanapplyExpand.setBillStatus(StatusContexts.BZJ_STATUS_RUN);
			loanapplyExpand.setLoanapply_no(loan.getLoanapplyNo());
			loanapplyExpandService.updateWorkFlow(loanapplyExpand);
		} else {
			return modelResult.getErrMsg();
		}
		return null;
	}

	@Override
	public LoanapplyExpand queryExpand(String loanapplyNo) {
		String sql = "SELECT * from o2o_loanapply_expand o WHERE o.loanapply_no = ?";
		return mainStoreInfoDao.findEntity(sql, LoanapplyExpand.class, loanapplyNo);
	}

	@Override
	public String downLoadGACFile(HttpServletResponse httpServletResponse, HttpServletRequest request,
			String loanapplyNo) {
		O2oLoanapplyEntity loan = loanService.findById(loanapplyNo);
		if (StringUtils.isEmpty(loan.getBankAccount()) || StringUtils.isEmpty(loan.getReceiveBank())) {
			return "请先保存银行卡信息";
		}
		// 最后需要生产的模板文件
				String classPathFiles = "/wordTemplate/2gacz.xml";
//				Map<String, Object> data = fillData(loanapplyNo);
				Map<String, Object> data = fillDataXML(loanapplyNo);
				OutputStream os = null;
				try {
					String outfile = "";
					outfile = "村镇银行带数据合同.doc";
					if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
						outfile = URLEncoder.encode(outfile, "UTF-8");
					} else {
						outfile = new String(outfile.getBytes("UTF-8"), "ISO8859-1");
					}
					os = httpServletResponse.getOutputStream();
					httpServletResponse.reset();
					httpServletResponse.setContentType("application/doc");
					httpServletResponse.setHeader("Content-Disposition", "attachment; filename=" + outfile);
					WordBuilder.buildDocFromXml(os, data, classPathFiles);
				} catch (IOException e) {
					throw new RuntimeIOException(e);
				} finally {
					IoUtil.close(os);
				}
		return null;
	}
	
	/**
	 * @Description:
	 *               <p>
	 *               填充XML数据
	 *               </p>
	 * @author LMX
	 * @date 2017年11月28日 下午1:50:48
	 */
	private Map<String, Object> fillDataXML(String loanapplyNo) {
		Map<String, Object> data = new HashMap<>();
		O2oLoanapplyEntity loanapply = loanService.findById(loanapplyNo);
		NumberFormat nf = new DecimalFormat(",###.00");
		O2oLoanUserEntity loanUserEntity = loanUserService.findById(loanapply.getLoanId(), loanapplyNo);
		LoanapplyExpand applyExpand = loanapplyExpandService.queryLoanapplyNo(loanapplyNo);
		CustomerBasicInfo customer = loanService.getCustomerEntityById(loanUserEntity.getId());
		CustomerAssetInfo asset = assetInfoService.queryById(loanapplyNo);
		O2oMainShopInfoEntity shop = mainShopInfoService.getByLoanNo(loanapplyNo);
//		CustomerShopInfoEntity shop = new CustomerShopInfoEntity();
//		List<CustomerShopInfoEntity> infoList = shopInfoService.list(loanapplyNo);//门店
//		if (!infoList.isEmpty()) {
//			if (infoList.size() > 1) {
//				for (CustomerShopInfoEntity shopInfo : infoList) {
//					if (shopInfo.getShoptype().equals("MAN")) {// 客户主门店里面的营业面积
//						shop = shopInfo;
//					}
//				}
//			} else {
//				shop = infoList.get(0);
//			}
//		}
		
		if (loanapply != null) {
			ActOrgEntity actOrgEntity = sysOrgService.getOrgByUnitNo(loanapply.getLtd());
			
			if (loanapply.getOperationModel().equals("PTDB")) {
				data.put("aName", actOrgEntity.getOrgFullName());// 甲方
				data.put("aAddress",  actOrgEntity.getOfficeAddress());// 甲方地址
			} else {
				data.put("aName", "深圳市怡亚通流通服务有限公司");// 甲方
				data.put("aAddress",  "深圳市前海深港合作区前湾一路1号A栋201室");// 甲方地址
			}
			
			data.put("ltd_mobile", actOrgEntity.getSponsorTel());// 经营单位电话
			data.put("ltd_office_address", actOrgEntity.getOfficeAddress());// 经营单位办公地址
			data.put("ltd_name", actOrgEntity.getOrgFullName());// 经营名称
			
			data.put("receiveBank", loanapply.getReceiveBank());// 借款银行名称
			data.put("open_account_bank_full_name", loanapply.getReceiveBank());// 借款银行名称
			data.put("guarantee_way_xinyong", "信用");// 担保方式
			data.put("bankActno", loanapply.getBankActno());// 贷款账号
			data.put("billCode", "国安-借-" + loanapply.getBillCode());// 贷款编号
			data.put("billCode1", "村镇银行-合-" + loanapply.getBillCode());// 协议编号
			if (!"".equals(loanapply.getEaMount()) && loanapply.getEaMount() != null) {
				String bankAmountBigWrite = MoneyUtil
						.toChinese(formatComma2BigDecimal(loanapply.getEaMount(),2).toString());
				System.out.println(bankAmountBigWrite);
				
				data.put("${bankAmountBigWrite}", bankAmountBigWrite);// 银行批复金额大写
				data.put("${bankAmountBigWrite-2}", bankAmountBigWrite.substring(0, bankAmountBigWrite.length() - 2));// 银行复批金额大写去‘元整’
				
				data.put("${bankAmount}", "￥" + formatComma2BigDecimal(loanapply.getEaMount(),2));// 申请金额万元
				data.put("${bankAmount}", nf.format(formatComma2BigDecimal(loanapply.getEaMount(),2)));// 银行批复金额小写
				
				String[] mountItem = buildMountNumber(loanapply.getEaMount());
				for (int i = 0; i < mountItem.length; i++) {
					data.put("mountItem" + i, mountItem[i]);
				}
			}
			
			if (loanapply.getLoanrate() != null) {
				BigDecimal loanrate = loanapply.getLoanrate().multiply(new BigDecimal(100));
				data.put("loanrate", formatComma2BigDecimal(loanrate,2).toString());// 借款利率
			}
			data.put("loanTerm", loanapply.getLoanTerm()+"");// 借款期限
			if (loanapply.getRepayMentway() != null) {
				if (loanapply.getRepayMentway().equals("AKT")) {
					data.put("repayMentway", "等额本金");// 还款方式
					data.put("${repayMentwayNo}", "(2)");
				} else if (loanapply.getRepayMentway().equals("RMT")) {
					data.put("repayMentway", "按月付息，到期还本");// 还款方式
					data.put("${repayMentwayNo}", "(1)");
				} else {
					data.put("repayMentway", "等额本息");// 还款方式
					data.put("${repayMentwayNo}", "(2)");
				}
			}
			
			data.put("bank_account", loanapply.getBankAccount());// 银行卡号(放款和还款卡号)
			
			if (loanapply.getGuarAnteeWay() != null) {
				
				PubDditem p = pubDditemService.queryPubDditem("9941", loanapply.getGuarAnteeWay());
				if (p != null) {
					data.put("guar_antee_way", p.getItemName());// 担保方式
				}
			}
			
			if (loanapply.getManagefeerate() != null) {
				BigDecimal managefeerate = loanapply.getManagefeerate().multiply(new BigDecimal(100));
				data.put("managefeerate", formatComma2BigDecimal(managefeerate,2).toString());// 管理费率
			}
			if (loanapply.getDepositrate() != null) {
				BigDecimal depositrate = loanapply.getDepositrate().multiply(new BigDecimal(100));
				data.put("depositrate", formatComma2BigDecimal(depositrate,2).toString());// 保证金费率
			}
			
			if (loanapply.getRisk() != null) {
				BigDecimal saferate = loanapply.getRisk().multiply(new BigDecimal(100));
				data.put("saferate", formatComma2BigDecimal(saferate,4).toString());// 风险补偿金费率
			}
			
			data.put("paymentType", "资金周转");// 借款用途
			
			
			
		}
		
		data.put("lonerName", loanUserEntity.getUserFullName());// 借款人
		data.put("age", IdNOToAge(loanUserEntity.getDocumentNo())+"");// 借款人年龄
		String sex = "";
		if ("F".equals(loanUserEntity.getSex())) {
			sex = "女";
		} else if ("M".equals(loanUserEntity.getSex())) {
			sex = "男";
		}
		data.put("sex", sex);// 借款人性别
		data.put("idNumber", loanUserEntity.getDocumentNo());// 身份证号码
		data.put("mobile", loanUserEntity.getUserPhone());// 手机号
		
		if (customer != null) {
			
			String recipientAddress=getRecipientAdress(customer);
			data.put("recipientAddress",recipientAddress );// 收件地址
			
			String countAdress=getCountAdress(customer);
			data.put("countAdress", countAdress);// 户籍地址
			
			if (customer.getAccountProvince() != null) {
				PubDditem p = pubDditemService.queryPubDditem("159", customer.getAccountProvince());
				if (p != null) {
					data.put("accountProvince", p.getItemName());// 户口所在省
				}
			}
			
			if (customer.getAccountCity() != null) {
				PubDditem p = pubDditemService.queryPubDditem("160", customer.getAccountCity());
				if (p != null) {
					data.put("accountCity", p.getItemName());// 户口所在市区
				}
			}
			if (customer.getEducation() != null) {
				PubDditem p = pubDditemService.queryPubDditem("107", customer.getEducation());
				if (p != null) {
					data.put("education", p.getItemName());// 学历
				}
			}
			
		}else{
			data.put("recipientAddress", "");// 收件地址
			data.put("countAdress", "");// 户籍地址
			data.put("accountProvince", "");// 户口所在省
			data.put("accountCity", "");// 户口所在市区
			data.put("education", "");// 学历
		}
		
		if (asset != null) {
			data.put("ownEstateNum", asset.getOwnEstateNum()+"");// 自有房产数量
			data.put("mortgageNum", asset.getMortgageNum()+"");// 按揭房产数量
			data.put("notmortgageNum", (asset.getOwnEstateNum() - asset.getMortgageNum())+"");// 按揭房产数量
			data.put("ownVehiclesNum", asset.getOwnVehiclesNum()+"");// 自有车辆数
			data.put("unsecuredNum", asset.getUnsecuredNum()+"");// 无抵押车辆数
			data.put("vehicleMortgageNum", asset.getVehicleMortgageNum()+"");// 辆数按揭数量
			
		}
		if (shop != null) {
			
			if (!"".equals(shop.getStupdate()) && shop.getStupdate() != null) {
				String year = DateUtils.formateStandDateTime(shop.getStupdate()).substring(0, 4);
				String mouth = DateUtils.formateStandDateTime(shop.getStupdate()).substring(5, 7);
				data.put("year", year);// 门店成立年
				data.put("mouth", mouth);// 门店成立月
			}else {
				data.put("year", "");// 门店成立年
				data.put("mouth", "");// 门店成立月
			}
			String Businesshours="";
			if (shop.getBusinesshours()!=null) {
				Businesshours= new SimpleDateFormat("yyyy-MM-dd").format(shop.getBusinesshours());
			}
			String mainShopAdd="";
			if (!StringUtils.isEmpty(shop.getShopprovince())) {
				String province=ddItemService.findPubdditemNameByCodeisall("province", shop.getShopprovince());
				if (!StringUtils.isEmpty(province)) {
					mainShopAdd+=province;
				}
			}
			if (!StringUtils.isEmpty(shop.getShopcity())) {
				String city=ddItemService.findPubdditemNameByCodeisall("city", shop.getShopcity());
				if (!StringUtils.isEmpty(city)) {
					mainShopAdd+=city;
				}
			}
			if (!StringUtils.isEmpty(shop.getShopcounty())) {
				String country=ddItemService.findPubdditemNameByCodeisall("country", shop.getShopcounty());
				if (!StringUtils.isEmpty(country)) {
					mainShopAdd+=country;
				}
			}
			mainShopAdd+=shop.getShopaddress();
			String organizationForm="";
			if (!StringUtils.isEmpty(shop.getOrganizationForm())) {
				organizationForm=ddItemService.findPubdditemO2ONameByCodeall("organizationForm", shop.getOrganizationForm());
			}
			String officeaddress="";
			if (!StringUtils.isEmpty(shop.getOfficeprovince())) {
				String province=ddItemService.findPubdditemNameByCodeisall("province", shop.getOfficeprovince());
				if (!StringUtils.isEmpty(province)) {
					officeaddress+=province;
				}
			}
			if (!StringUtils.isEmpty(shop.getOfficecity())) {
				String city=ddItemService.findPubdditemNameByCodeisall("city", shop.getOfficecity());
				if (!StringUtils.isEmpty(city)) {
					officeaddress+=city;
				}
			}
			if (!StringUtils.isEmpty(shop.getOfficecounty())) {
				String country=ddItemService.findPubdditemNameByCodeisall("country", shop.getOfficecounty());
				if (!StringUtils.isEmpty(country)) {
					officeaddress+=country;
				}
			}
			officeaddress+=shop.getOfficeaddress();
			data.put("controllername", loanUserEntity.getUserFullName());// 借款人
			data.put("controllerIdnum", loanUserEntity.getDocumentNo());// 身份证号码
			data.put("controllerMobile", loanUserEntity.getUserPhone());// 手机号
			data.put("mainShopAdd", mainShopAdd);// 门店地址
			data.put("businesshours", Businesshours);// 营业时间
			data.put("${officeaddress}", officeaddress);// 已方单位地址
			data.put("licenceName", shop.getLicenceName());// 营业执照名称
			data.put("blrNumber", shop.getBlrNumber());// 营业执照注册号
			data.put("organizationForm", organizationForm);//组织形式
//			data.put("shopTelephone", shop.getTelephone());//门店电话
//			data.put("${businessarea}", String.valueOf(shop.getBusinessarea()));// 客户主门店里面的营业面积
//			data.put("${mainproducts}", shop.getMainproducts());// 主要经营产品
			data.put("shopTelephone", "");//门店电话
			data.put("${businessarea}", "");// 客户主门店里面的营业面积
			data.put("${mainproducts}", "");// 主要经营产品
		}else {
			data.put("controllername", "");// 借款人
			data.put("controllerIdnum", "");// 身份证号码
			data.put("controllerMobile", "");// 手机号
			data.put("mainShopAdd", "");// 门店地址
			data.put("businesshours", "");// 营业时间
			data.put("${officeaddress}", "");// 已方单位地址
			data.put("licenceName", "");// 营业执照名称
			data.put("blrNumber", "");// 营业执照注册号
			data.put("organizationForm", "");//组织形式
			data.put("${officeaddress}", "");// 已方单位地址
			data.put("year", "");// 门店成立年
			data.put("mouth", "");// 门店成立月
			data.put("shopTelephone", "");//门店电话
			data.put("${businessarea}", "");// 客户主门店里面的营业面积
			data.put("${mainproducts}", "");// 主要经营产品
		}
		
		if (applyExpand != null) {
			if (applyExpand.getRecManger() != null) {
				System.out.println("管理费:" + formatComma2BigDecimal(applyExpand.getRecManger(),2));
				data.put("rec_manger", "￥" + formatComma2BigDecimal(applyExpand.getRecManger(),2));// 管理费
			}
			if (applyExpand.getRecDeposite() != null) {
				data.put("rec_deposite", "￥" + formatComma2BigDecimal(applyExpand.getRecDeposite(),2));// 保证费
			}
			if (applyExpand.getRecRisk() != null) {
				data.put("rec_risk", "￥" + formatComma2BigDecimal(applyExpand.getRecRisk(),2));// 保证费
			}
			BigDecimal total = new BigDecimal("0");
			BigDecimal recManger = new BigDecimal("0");
			BigDecimal recDeposite = new BigDecimal("0");
			BigDecimal recRisk = new BigDecimal("0");
			recManger = applyExpand.getRecManger() == null ? recManger : applyExpand.getRecManger();
			recDeposite = applyExpand.getRecDeposite() == null ? recDeposite : applyExpand.getRecDeposite();
			recRisk = applyExpand.getRecRisk() == null ? recRisk : applyExpand.getRecRisk();
			total = recManger.add(recDeposite).add(recRisk);
			data.put("rec_total_samll", formatComma2BigDecimal(total,2).toString());// 保证费
			data.put("rec_total_big", MoneyUtil.toChinese(formatComma2BigDecimal(total,2).toString()));// 保证费
			
		}
		//担保人
		O2oLoanUserEntity guarantorByGuara = loanUserService.queryDBById(loanapplyNo);
		if (guarantorByGuara != null) {
			data.put("guarByGuara", guarantorByGuara.getUserFullName());// 担保人
			data.put("guarIdCardByGuara", guarantorByGuara.getDocumentNo());// 担保人身份证
			data.put("guarMobileByGuara", guarantorByGuara.getUserPhone());// 担保人电话号码
		}else{
			data.put("guarByGuara", "");// 担保人
			data.put("guarIdCardByGuara", "");// 担保人身份证
			data.put("guarMobileByGuara", "");// 担保人电话号码
		}
		
		O2oLoanUserEntity loanSpouseUserEntity = loanUserService.findSpouseId(loanUserEntity.getLoanId(), loanapplyNo);
		if (loanSpouseUserEntity != null) {
			data.put("mateName", loanSpouseUserEntity.getUserFullName());// 配偶
			data.put("mateIdCard", loanSpouseUserEntity.getDocumentNo());// 配偶身份证
			data.put("mateMobile", loanSpouseUserEntity.getUserPhone());// 配偶手机号
			
			CustomerBasicInfo mateBasicInfo = loanService.getCustomerEntityById(loanSpouseUserEntity.getId());
			
			if (mateBasicInfo != null) {
				String recipientAdress = getCountAdress(mateBasicInfo);
				data.put("mateRecipientAdress", recipientAdress);// 配偶收件地址
				data.put("work_unit", mateBasicInfo.getWorkUnit());// 配偶工作单位
			} 
		} else {
			data.put("mateName", "");// 配偶
			data.put("mateIdCard", "");// 配偶身份证
			data.put("mateMobile", "");// 配偶手机号
			data.put("mateRecipientAdress", "");// 配偶收件地址
			data.put("work_unit", "");// 配偶工作单位
		}
		return data;
		
	}
	private BigDecimal formatComma2BigDecimal(Object obj,int num) {
		String val = String.valueOf(obj);
		if (val == null)
			return new BigDecimal("0.00");

		val = val.replaceAll(",", "");
		if (!isNumber(val))
			return new BigDecimal("0.00");

		BigDecimal decimal = new BigDecimal(val);
		decimal = decimal.setScale(num, BigDecimal.ROUND_UP);

		return decimal;

	}
	
	private boolean isNumber(String value) {
		return isInteger(value) || isDouble(value);
	}
	
	private boolean isDouble(String value) {
		try {
			Double.parseDouble(value);
			if (value.contains("."))
				return true;
			return false;
		} catch (NumberFormatException e) {
			return false;
		}
	}

	private boolean isInteger(String value) {
		try {
			Integer.parseInt(value);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}
	
	private static String[] buildMountNumber(Number number) {
		DecimalFormat df = new DecimalFormat("0.00");
		String mountStr = df.format(number);
		mountStr = "￥" + mountStr.replace(".", "");
		String[] numberArray = new String[10];
		int j = 0;
		for (int i = 0; i < numberArray.length; i++) {
			numberArray[i] = "";
			if (mountStr.length() >= 10 - i) {
				numberArray[i] = mountStr.substring(j, j + 1);
				j++;
			}
		}
		return numberArray;
	}
	
	// 根据身份证号输出年龄
		public static int IdNOToAge(String IdNO) {
			int leh = IdNO.length();
			String dates = "";
			if (leh == 18) {
				dates = IdNO.substring(6, 10);
				SimpleDateFormat df = new SimpleDateFormat("yyyy");
				String year = df.format(new Date());
				int u = Integer.parseInt(year) - Integer.parseInt(dates);
				return u;
			} else {
				dates = IdNO.substring(6, 8);
				return Integer.parseInt(dates);
			}

		}
		
		private String getRecipientAdress(CustomerBasicInfo basic) {
			String recipientAdress = "";
			if (StringUtil.isNotBlank(basic.getRecipientProvince())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("9", basic.getRecipientProvince());
				if (p != null) {
					recipientAdress = recipientAdress + p.getItemName();
				}
			}

			if (StringUtil.isNotBlank(basic.getRecipientCity())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("10", basic.getRecipientCity());
				if (p != null) {
					recipientAdress = recipientAdress + p.getItemName();
				}
			}

			if (StringUtil.isNotBlank(basic.getRecipientCounty())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("11", basic.getRecipientCounty());
				if (p != null) {
					recipientAdress = recipientAdress + p.getItemName();
				}
			}

			if (basic.getRecipientAddress() != null) {
				recipientAdress = recipientAdress + basic.getRecipientAddress();
			}
			return recipientAdress;

		}
		
		private String getCountAdress(CustomerBasicInfo basic) {
			String acountAdress = "";
			if (StringUtil.isNotBlank(basic.getAccountProvince())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("9", basic.getAccountProvince());
				if (p != null) {
					acountAdress = acountAdress + p.getItemName();
				}
			}

			if (StringUtil.isNotBlank(basic.getAccountCity())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("10", basic.getAccountCity());
				if (p != null) {
					acountAdress = acountAdress + p.getItemName();
				}
			}

			if (StringUtil.isNotBlank(basic.getAccountAounty())) {
				PubDditem p = pubDditemService.queryPubDditemCRM("11", basic.getAccountAounty());
				if (p != null) {
					acountAdress = acountAdress + p.getItemName();
				}
			}

			if (basic.getPermanentresidence() != null) {
				acountAdress = acountAdress + basic.getPermanentresidence();
			}
			return acountAdress;

		}

		@Override
		public int getDCLoanAccount(String loanId) {
			return o2oLoanapplyService.findDCLoan(loanId);
		}

		@Override
		public O2OSpecialInterview getSpecialByLoannapply(String loanapplyNo) {
			return o2OSpecialInterviewService.fingHasFlow(loanapplyNo);
		}

		@Override
		public String submitSpecialApproval(String loanapplyNo) {
			if (StringUtil.isEmpty(loanapplyNo)) {
				return "贷款单号不能为空";
			}
			O2oLoanapplyEntity entity = o2oLoanapplyService.findById(loanapplyNo);
			//是否已经存在特殊申报流程
			O2OSpecialInterview o2OSpecialInterview = o2OSpecialInterviewService.queryEntity(loanapplyNo);
			 if(o2OSpecialInterview==null){
				 O2OSpecialInterview o2OSpecialInterviewAdd = new O2OSpecialInterview();
				 o2OSpecialInterviewAdd.setBillCode(entity.getBillCode());
				 o2OSpecialInterviewAdd.setLoanapplyNo( entity.getLoanapplyNo());
				 o2OSpecialInterviewAdd.setBillStatus(StatusContexts.WFTYPE_STATUS_NEW);
				 o2OSpecialInterviewAdd.setCreatorId(userUtils.getCreateOr());
				 o2OSpecialInterviewAdd.setCreatTime(userUtils.getCreateTime());
				 o2OSpecialInterviewAdd.setCreatorName(userUtils.getUserName());
				 o2OSpecialInterviewAdd.setIslock(StatusContexts.O2O_NO);
				 o2OSpecialInterviewService.save(o2OSpecialInterviewAdd);
			 }
			 BaseRestResult<String> reslut = startUp(entity.getLoanapplyNo());
			 if(reslut.getAction().equals(BaseRestResult.ACTION_INFO)){
				 return null;
			 }else{
				 return reslut.getMessage();
			 }
		}
		
		public BaseRestResult<String> startUp(String referId) {
			 O2OSpecialInterview o2OSpecialInterviewStart = o2OSpecialInterviewService.queryEntity(referId);
			O2oLoanapplyEntity apply = null;
			apply = o2oLoanapplyService.fingByBillCode(o2OSpecialInterviewStart.getBillCode());
			// 存库成功 启动退费流程
			ModelResult<Boolean> modelResult = startMQSB(apply);
			// 流程启动后更新主表
			logger.info("start-up Technological process result params isSuccess:{},ErrCode:{},ErrMsg:{},etailStack:{}", modelResult.isSuccess(), modelResult.getErrCode(), modelResult.getErrMsg(), modelResult.getDetailStack());
			if (modelResult.isSuccess()) {
				o2OSpecialInterviewService.updateWorkFlowStatus(StatusContexts.WFTYPE_STATUS_RUN, apply.getLoanapplyNo());
				// 流程启动后更新主表
				//return BaseRestResult.info("操作成功").andRedirect(UrlHelper.build("/backfee/list"));
				return BaseRestResult.info("操作成功");
			}
			
			return BaseRestResult.warn(modelResult.getErrMsg());
		}
		
		/**
		 * 启动特殊面签流程
		 */
		public ModelResult<Boolean> startMQSB(O2oLoanapplyEntity loan) { // 根据单号去启动流程
			logger.info("贷款编号：[{}],贷款类型：[{}],启动特殊面签流程", loan.getBillCode(),loan.getLoanType());
			WFRequestParam param = new WFRequestParam();
			param.setReferId(loan.getLoanapplyNo());
			param.setReferCode(loan.getBillCode());
			param.setReferUrl("http://xxxx.eascs.com/getDetail");
			param.setSystemModule(ProcessTemplate.SYSTEM_MODULE_O2O);
			param.setProcessType(String.valueOf(ProcessTemplate.PROECESS_TYPE_SPEC_BANK_REPORT));
			param.setProcessVersion("v1");
			User user = UserHolder.getUser();
			param.setAppliedby(user.getNo());
			param.setAppliedbyName(user.getCname());
			param.setOrgNo(loan.getLtd());
			param.setLoginUser(UserUtils.getUser(user));
			StringBuffer appliedDes = new StringBuffer("借款人:");
			appliedDes.append(o2oLoanapplyService.findLoanUserEntity(loan.getLoanapplyNo(),loan.getLoanId()).getUserFullName());
			appliedDes.append("，申请金额:");
			java.text.DecimalFormat df=new java.text.DecimalFormat("0.00"); //格式化，保留两位小数
			appliedDes.append(df.format(loan.getLoanaMount().doubleValue()));
			param.setAppliedDes(appliedDes.toString());
			logger.info("启动特殊面签流程WFRequestParam对象：[{}]", param.toString());
			ModelResult<Boolean> modelResult = workFlowService.instance(param);
			return modelResult;
		}
		
}
